﻿using DotNetCore.CAP;
using DotNetCore.CAP.Transport;
using FreeSql;

namespace TK.Common.CAP
{
    /// <summary>
    /// freesql cap 事务
    /// </summary>
    public class FreeSqlCapTransaction : CapTransactionBase
    {
        public FreeSqlCapTransaction(IDispatcher dispatcher, IUnitOfWork uow) : base(dispatcher)
        {
            Uow = uow;
        }

        public IUnitOfWork Uow { get; }

        public override object? DbTransaction => Uow.GetOrBeginTransaction();

        public override void Commit()
        {
            Uow.Commit();
            Flush();
        }

        public override Task CommitAsync(CancellationToken cancellationToken = default)
        {
            return Task.Run(() => Commit());
        }

        public override void Rollback()
        {
            Uow.Rollback();
        }

        public override Task RollbackAsync(CancellationToken cancellationToken = default)
        {
            return Task.Run(()=>Rollback());
        }

        public override void Dispose()
        {
            Uow.Dispose();
        }
    }

    public static class FreeSqlCapTransactionExtension
    {
        public static ICapTransaction BeginTransaction(this IFreeSql freeSql,
            ICapPublisher publisher, out IRepositoryUnitOfWork uow, bool autoCommit = false)
        {
            var dispatcher = publisher.ServiceProvider.GetRequiredService<IDispatcher>();
            uow = freeSql.CreateUnitOfWork();
            var transaction = new FreeSqlCapTransaction(dispatcher, uow)
            {
                AutoCommit = autoCommit
            };
            return publisher.Transaction.Value = transaction;
        }
    }
}
